﻿module Sustainalytics.Authentication {

    export class AuthenticationService implements IAuthenticationService {

        private urlBase: string;

        constructor(
            private $q: ng.IQService,
            private $http: ng.IHttpService,
            private staticObjects: IStaticObjects,
            private $location: ng.ILocationService,
            private $rootScope: RootScope) {

            var ctx = this;

            ctx.init();
        }

        private init(): void {
            var ctx = this;

            ctx.urlBase = ctx.staticObjects.authBaseUrl;
        }

        public login(userCredentials): ng.IHttpPromise<AuthData> {
            var ctx = this;

            var promise = ctx.$http.post(ctx.urlBase + "/token", userCredentials);

            return promise;
        }

        public logout(redirectTo?: string, err?: number) {
            var ctx = this;

            localStorage.removeItem('sust_refresh_token');
            localStorage.removeItem('sust:a:ur');
            localStorage.removeItem('sust_userInfo');
            ctx.staticObjects.clearUserInfo();

            var urlParams = $.param(
                {
                    redirectTo: redirectTo ? encodeURI(redirectTo) : null,
                    err: err ? encodeURI(err.toString()) : null
                });

            ctx.$location.url('/login' + (redirectTo || err ? '?' + urlParams : ''));
            //window.location.reload(true);
        }

        public profile(): ng.IHttpPromise<IUserInfo> {
            var ctx = this;

            var promise = ctx.$http.post(ctx.urlBase + "/api/account/profile", null);

            return promise;
        }

        public refreshToken(): ng.IPromise<any> {

            var ctx = this;

            var def = ctx.$q.defer();

            var sustRefreshToken = localStorage.getItem('sust_refresh_token');

            if (sustRefreshToken) {
                var token = JSON.parse(sustRefreshToken);

                var loginParams =
                    "grant_type=refresh_token" +
                    "&refresh_token=" + token.refreshToken +
                    "&client_id=clientId1" +
                    "&client_secret=secret1";

                ctx.login(loginParams)
                    .success((authData: AuthData) => {
                        if (!authData.access_token && !authData.expires_in && !authData.refresh_token) {
                            //ctx.staticObjects.redirectToLogin();
                            def.reject();
                        }
                        else {
                            authData.loginTime = new Date();

                            ctx.$rootScope.authData = authData;

                            token.refreshToken = authData.refresh_token
                            localStorage.setItem('sust_refresh_token', JSON.stringify(token));

                            window.setTimeout(() => {

                                // redirect to login if the refresh token failed
                                ctx.refreshToken()['catch'](function () {
                                    ctx.staticObjects.redirectToLogin();
                                });

                            }, (authData.expires_in - 5) * 1000);

                            ctx.profile()
                                .success((userInfo: IUserInfo) => {
                                    ctx.$rootScope.userInfo = userInfo;
                                    def.resolve();
                                })
                                .error((userInfo: IUserInfo) => {
                                    ctx.staticObjects.errorCallback.apply(ctx.staticObjects, arguments);
                                    def.reject();
                                });
                        }
                    })
                    .error(() => {
                        //ctx.staticObjects.redirectToLogin();
                        def.reject();
                    });
            }
            else {                
                //ctx.staticObjects.redirectToLogin();
                def.reject();
            }

            return def.promise;
        }

        public forgotPassword(username: string): ng.IHttpPromise<any> {
            var ctx = this;
            var promise = ctx.$http.post(ctx.urlBase + "/api/account/forgotPassword", username);
            return promise;
        }

        public changePassword(changePasswordParams): ng.IHttpPromise<any> {
            var ctx = this;
            var promise = ctx.$http.post(ctx.urlBase + "/api/account/changePassword", changePasswordParams);
            return promise;
        }

        public permissions(): ng.IHttpPromise<Sustainalytics.Claims.ActiveResourcesDto[]> {
            var ctx = this;
            var promise = ctx.$http.get("/claimsserv/api/v1/claims");

            promise
                .success((resources: Sustainalytics.Claims.ActiveResourcesDto[]) => {
                    ctx.staticObjects.resourcePermissions = angular.toJson(resources);
                    // backup
                    localStorage.setItem("sust:a:ur", angular.toJson(resources));
                });

            return promise;
        }
    }

    export var authenticationServiceName = 'AuthenticationService';

    angular.module(authenticationModuleName).service(authenticationServiceName, AuthenticationService);
} 